﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Reflection;

namespace ProgNetUtils
{
    public class ReflectionHelper
    {
        #region [===== Public static methods =====]
        /// <summary>
        /// Returns the current value of a provided property for a specific component.
        /// </summary>
        /// <param name="provider">The provider which manages the <paramref name="property"/>.</param>
        /// <param name="property">The property to get the value for.</param>
        /// <param name="component">The component to get the value for.</param>
        /// <returns>The value of the <paramref name="property"/> for <paramref name="component"/>.</returns>
        public static object GetCurrentValue(IExtenderProvider provider, ProvidePropertyAttribute property,
            IComponent component)
        {
            Type type = provider.GetType();
            MethodInfo method = type.GetMethod("Get" + property.PropertyName);
            return method.Invoke(provider, new object[] { component });
        }

        /// <summary>
        /// Returns a value indicating whether a provided property has a default value.
        /// </summary>
        /// <param name="provider">The provider which manages the <paramref name="property"/>.</param>
        /// <param name="property">The property to verify.</param>
        /// <returns><b>True</b> when the <paramref name="property"/> has a default value,
        /// otherwise <b>False</b>.</returns>
        public static bool HasDefaultValue(IExtenderProvider provider, ProvidePropertyAttribute property)
        {
            Type type = provider.GetType();
            MethodInfo method = type.GetMethod("Get" + property.PropertyName);
            return method.GetCustomAttributes(typeof(DefaultValueAttribute), true).Length != 0;
        }

        /// <summary>
        /// Returns the default value for a provided property.
        /// </summary>
        /// <param name="provider">The provider which manages the <paramref name="property"/>.</param>
        /// <param name="property">The property to get the default value for.</param>
        /// <returns>The default value of <paramref name="property"/> (which can be null),
        /// otherwise null.</returns>
        public static object GetDefaultValue(IExtenderProvider provider, ProvidePropertyAttribute property)
        {
            Type type = provider.GetType();
            MethodInfo method = type.GetMethod("Get" + property.PropertyName);
            DefaultValueAttribute[] attributes = (DefaultValueAttribute[])method.GetCustomAttributes(typeof(DefaultValueAttribute), true);
            return attributes.Length > 0 ? attributes[0].Value : null;
        }
        #endregion
    }
}
